package graphics.objects;
import org.lwjgl.opengl.GL11;

import tools.Floatmath;
import tools.Help;
import tools.Log;
import tools.Point;
import graphics.effects.Compositor;
import graphics.system.Color;
import graphics.system.GLTools;
import graphics.system.Texture;
import graphics.system.TextureContainer;
public class GRect extends GShape {
	private float width;
	private float height;
	private Point verts[];
	public GRect(Point pos, float width, float height, float angle, Color color) {
		super(pos, angle, color);
		hasTexture = false;
		this.width = width;
		this.height = height;
		node.setBoundingRad(Floatmath.sqrt((width / 2) * (width / 2) + (height / 2) * (height / 2)));
		verts = new Point[]{new Point(width / 2, height / 2), new Point(-width / 2, height / 2), new Point(-width / 2, -height / 2), new Point(width / 2, -height / 2)};
		glowscale = 4;
		globalCoords = false;
		hasNormalmap = false;
	}
	public GRect(Point pos, float width, float height, float angle, String texname) {
		this(pos, width, height, angle, Color.white);
		this.texture = TextureContainer.getTexture(texname);
		hasTexture = true;
	}
	@Override
	public void draw() {
		if (!hasTexture) {
			GL11.glPushMatrix();
			node.setUpGl();
			GLTools.drawRect(Point.ZERO, width, height, 0, color);
			GL11.glPopMatrix();
		}
		else {
			if (!globalCoords) {
				GL11.glPushMatrix();
				node.setUpGl();
				GLTools.drawTexRectYmirror(Point.ZERO, width, height, 0, texture.getTexID(), color);
				GL11.glPopMatrix();
			}
			else {
				GL11.glPushMatrix();
				color.set();
				this.texture.bind();
				GL11.glEnable(GL11.GL_TEXTURE_2D);
				GL11.glBegin(GL11.GL_QUADS);
				for (int i = 0; i < 4; i++) {
					Point cp = verts[i].rotate(node.apos);
					cp.x *= node.scale.x;
					cp.y *= node.scale.y;
					cp.sAdd(node.pos);
					GL11.glTexCoord2f(cp.x * this.globalCoordScale, cp.y * this.globalCoordScale);
					GL11.glVertex2f(cp.x, cp.y);
				}
				GL11.glEnd();
				GL11.glDisable(GL11.GL_TEXTURE_2D);
				GL11.glPopMatrix();
			}
		}
	}
	@Override
	public void drawSpec(Point lightPos, float lradius, Color lc, float zoom) {
		if (hasNormalmap) {
			// GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE); //Additive blend
			Compositor.specular.enable();
			Compositor.specular.setParam2f("lpos", lightPos);
			Compositor.specular.setParamf("r", lc.r);
			Compositor.specular.setParamf("g", lc.g);
			Compositor.specular.setParamf("b", lc.b);
			Compositor.specular.setParamf("a", lc.a);
			if (globalCoords) {
				Compositor.specular.setParamf("ca", 1);
				Compositor.specular.setParamf("sa", 0);
			}
			else {
				Compositor.specular.setParamf("ca", Floatmath.cos(node.apos));
				Compositor.specular.setParamf("sa", Floatmath.sin(node.apos));
			}
			Compositor.specular.setParamf("radius", lradius);
			Compositor.specular.setParami("bumpmap", 0);
			Color.white.set();
			GL11.glPushMatrix();
			normalTexture.bind();
			GL11.glEnable(GL11.GL_TEXTURE_2D);
			GL11.glBegin(GL11.GL_QUADS);
			if (globalCoords) {
				for (int i = 0; i < 4; i++) {
					Point cp = verts[i].rotate(node.apos);
					cp.x *= node.scale.x;
					cp.y *= node.scale.y;
					cp.sAdd(node.pos);
					GL11.glTexCoord2f(cp.x * this.globalCoordScale, cp.y * this.globalCoordScale);
					GL11.glVertex2f(cp.x, cp.y);
				}
			}
			else {
				Point cp[] = new Point[4];
				for (int i = 0; i < 4; i++) {
					Point c = verts[i].rotate(node.apos);
					c.x *= node.scale.x;
					c.y *= node.scale.y;
					c.sAdd(node.pos);
					cp[i] = c;
				}
				GL11.glTexCoord2f(1, 1);
				GL11.glVertex2f(cp[0].x, cp[0].y);
				GL11.glTexCoord2f(0, 1);
				GL11.glVertex2f(cp[1].x, cp[1].y);
				GL11.glTexCoord2f(0, 0);
				GL11.glVertex2f(cp[2].x, cp[2].y);
				GL11.glTexCoord2f(1, 0);
				GL11.glVertex2f(cp[3].x, cp[3].y);
			}
			GL11.glEnd();
			GL11.glDisable(GL11.GL_TEXTURE_2D);
			GL11.glPopMatrix();
			Compositor.specular.disable();
		}
		else {
			// GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
			Compositor.enableShadowRender();
			this.draw();
			Compositor.disableShadowRender();
		}
	}
	@Override
	public void drawShadow(Point lightPos, float radius) {
		if (!this.hasShadow)
			return;
		GL11.glPushMatrix();
		node.setUpGl();
		if (!hasTexture) {
			GLTools.drawRect(Point.ZERO, width, height, 0, Color.black);
		}
		else {
			Compositor.enableShadowRender();
			GLTools.drawTexRectYmirror(Point.ZERO, width, height, 0, texture.getTexID(), Color.black);
			Compositor.disableShadowRender();
		}
		GL11.glPopMatrix();
		Point dx = node.pos.sub(lightPos).normalize().mul(radius * 10);
		GL11.glPushMatrix();
		GL11.glTranslatef(node.pos.x, node.pos.y, 0);
		GL11.glBegin(GL11.GL_QUADS);
		for (int i = 0; i < verts.length - 1; i++) {
			for (int j = i + 1; j < verts.length; j++) {
				Point s = verts[i].rotate(node.apos);
				Point e = verts[j].rotate(node.apos);
				s.x *= node.scale.x;
				s.y *= node.scale.y;
				e.x *= node.scale.x;
				e.y *= node.scale.y;
				Point b = s.add(s.add(node.pos).sub(lightPos).normalize().mul(radius * 5));
				Point d = e.add(e.add(node.pos).sub(lightPos).normalize().mul(radius * 5));
				GL11.glVertex2f(s.x, s.y);
				GL11.glVertex2f(e.x, e.y);
				GL11.glVertex2f(d.x, d.y);
				GL11.glVertex2f(b.x, b.y);
				s = b.add(dx);
				e = d.add(dx);
				GL11.glVertex2f(s.x, s.y);
				GL11.glVertex2f(e.x, e.y);
				GL11.glVertex2f(d.x, d.y);
				GL11.glVertex2f(b.x, b.y);
			}
		}
		GL11.glEnd();
		GL11.glPopMatrix();
	}
	public void drawGlow() {
		if (hasGlow) {
			GL11.glPushMatrix();
			node.setUpGl();
			if (!hasTexture)
				GLTools.drawRect(Point.ZERO, width + glowscale, height + glowscale, 0, glowColor);
			else {
				Compositor.enableShadowRender();
				GLTools.drawTexRectYmirror(Point.ZERO, width + glowscale, height + glowscale, 0, texture.getTexID(), glowColor);
				Compositor.disableShadowRender();
			}
			GL11.glPopMatrix();
		}
	}
	@Override
	public void drawDebug() {
		if (!hasTexture) {
			GL11.glPushMatrix();
			node.setUpGl();
			GLTools.drawRect(Point.ZERO, width, height, 0, color);
			GLTools.drawRectWire(Point.ZERO, width, height, 0, Color.blue);
			GL11.glPopMatrix();
		}
		else {
			if (!globalCoords) {
				GL11.glPushMatrix();
				node.setUpGl();
				GLTools.drawTexRectYmirror(Point.ZERO, width, height, 0, texture.getTexID(), color.withAlpha(0.5f));
				GLTools.drawRectWire(Point.ZERO, width, height, 0, Color.blue);
				GL11.glPopMatrix();
			}
			else {
				GL11.glPushMatrix();
				color.set();
				this.texture.bind();
				GL11.glEnable(GL11.GL_TEXTURE_2D);
				GL11.glBegin(GL11.GL_QUADS);
				for (int i = 0; i < 4; i++) {
					Point cp = verts[i].rotate(node.apos);
					cp.x *= node.scale.x;
					cp.y *= node.scale.y;
					cp.sAdd(node.pos);
					GL11.glTexCoord2f(cp.x * this.globalCoordScale, cp.y * this.globalCoordScale);
					GL11.glVertex2f(cp.x, cp.y);
				}
				GL11.glEnd();
				GL11.glDisable(GL11.GL_TEXTURE_2D);
				GL11.glPopMatrix();
			}
		}
	}
	@Override
	public String toFileString() {
		String s = super.toFileString();
		s = s + "/" + width + "/" + height;
		return s;
	}
	public int fromFileString(String s) {
		int off = super.fromFileString(s);
		String l[] = s.split("/");
		width = Float.valueOf(l[off + 1]);
		height = Float.valueOf(l[off + 2]);
		node.setBoundingRad(Floatmath.sqrt((width / 2) * (width / 2) + (height / 2) * (height / 2)));
		verts = new Point[]{new Point(width / 2, height / 2), new Point(-width / 2, height / 2), new Point(-width / 2, -height / 2), new Point(width / 2, -height / 2)};
		return off + 2;
	}
}
